import { _decorator, Component, Node, Vec3, Color } from 'cc';
import { GameManager } from './GameManager';
const { ccclass, property } = _decorator;

/**
 * 方块类型定义
 * 包含所有俄罗斯方块的形状数据
 */
const BLOCK_TYPES = [
    // I型方块
    [
        [1, 1, 1, 1]
    ],
    // O型方块
    [
        [1, 1],
        [1, 1]
    ],
    // T型方块
    [
        [0, 1, 0],
        [1, 1, 1]
    ],
    // S型方块
    [
        [0, 1, 1],
        [1, 1, 0]
    ],
    // Z型方块
    [
        [1, 1, 0],
        [0, 1, 1]
    ],
    // J型方块
    [
        [1, 0, 0],
        [1, 1, 1]
    ],
    // L型方块
    [
        [0, 0, 1],
        [1, 1, 1]
    ]
];

/**
 * 方块颜色
 * 对应不同类型方块的颜色
 */
const BLOCK_COLORS = [
    new Color(0, 255, 255), // 青色 - I型
    new Color(255, 255, 0), // 黄色 - O型
    new Color(128, 0, 255), // 紫色 - T型
    new Color(0, 255, 0),   // 绿色 - S型
    new Color(255, 0, 0),   // 红色 - Z型
    new Color(0, 0, 255),   // 蓝色 - J型
    new Color(255, 128, 0)  // 橙色 - L型
];

/**
 * 方块管理器
 * 负责生成、移动、旋转方块以及碰撞检测
 */
@ccclass('BlockManager')
export class BlockManager extends Component {
    // 游戏管理器引用
    @property(GameManager) 
    private gameManager: GameManager = null;
    
    // 单个小方块预制体引用
    @property(Node) 
    private cellPrefab: Node = null;
    
    // 游戏地图
    private map: number[][] = [];
    
    // 当前方块
    private currentBlock: Node[][] = [];
    
    // 当前方块类型
    private currentBlockType: number = 0;
    
    // 当前方块颜色
    private currentBlockColor: Color = Color.WHITE;
    
    // 当前方块在地图中的位置
    private currentRow: number = 0;
    private currentCol: number = 0;
    
    // 自动下落计时器
    private dropTimer: number = 0;
    
    // 自动下落间隔（秒）
    private dropInterval: number = 1.0;
    
    // 地图尺寸常量
    private readonly MAP_ROWS: number = 20;
    private readonly MAP_COLS: number = 10;
    
    /**
     * 组件加载时调用
     * 初始化地图和游戏
     */
    onLoad() {
        this.initMap();
        this.spawnNewBlock();
    }
    
    /**
     * 初始化游戏地图
     * 创建二维数组表示地图状态
     */
    initMap() {
        this.map = [];
        for (let i = 0; i < this.MAP_ROWS; i++) {
            this.map[i] = [];
            for (let j = 0; j < this.MAP_COLS; j++) {
                this.map[i][j] = 0; // 0表示空格子，1表示有方块
            }
        }
    }
    
    /**
     * 生成新方块
     * 随机选择方块类型并创建方块实例
     */
    spawnNewBlock() {
        // 随机选择方块类型
        this.currentBlockType = Math.floor(Math.random() * BLOCK_TYPES.length);
        this.currentBlockColor = BLOCK_COLORS[this.currentBlockType];
        
        const blockData = BLOCK_TYPES[this.currentBlockType];
        this.currentBlock = [];
        
        // 创建方块实例
        for (let i = 0; i < blockData.length; i++) {
            this.currentBlock[i] = [];
            for (let j = 0; j < blockData[i].length; j++) {
                if (blockData[i][j] === 1) {
                    // 创建小方块实例
                    const cell = cc.instantiate(this.cellPrefab);
                    cell.color = this.currentBlockColor;
                    this.node.addChild(cell);
                    this.currentBlock[i][j] = cell;
                } else {
                    this.currentBlock[i][j] = null;
                }
            }
        }
        
        // 设置初始位置（居中）
        this.currentRow = 0;
        this.currentCol = Math.floor((this.MAP_COLS - blockData[0].length) / 2);
        
        // 更新方块位置
        this.updateBlockPosition();
        
        // 检查游戏是否结束（新方块无法放置）
        if (!this.checkPositionValid(this.currentRow, this.currentCol)) {
            this.gameManager.gameOver();
        }
    }
    
    /**
     * 更新方块位置
     * 根据当前行列位置重新定位方块
     */
    updateBlockPosition() {
        for (let i = 0; i < this.currentBlock.length; i++) {
            for (let j = 0; j < this.currentBlock[i].length; j++) {
                if (this.currentBlock[i][j]) {
                    // 计算实际位置坐标
                    // 假设每个方块宽度为30像素
                    const x = (this.currentCol + j - this.MAP_COLS / 2) * 30;
                    const y = -this.currentRow * 30;
                    this.currentBlock[i][j].position = new Vec3(x, y, 0);
                }
            }
        }
    }
    
    /**
     * 检查位置是否有效
     * 验证方块在指定位置是否会发生碰撞
     * @param row 行位置
     * @param col 列位置
     * @returns 是否有效位置
     */
    checkPositionValid(row: number, col: number): boolean {
        for (let i = 0; i < this.currentBlock.length; i++) {
            for (let j = 0; j < this.currentBlock[i].length; j++) {
                if (this.currentBlock[i][j]) {
                    const newRow = row + i;
                    const newCol = col + j;
                    
                    // 检查边界
                    if (newRow < 0 || newRow >= this.MAP_ROWS || 
                        newCol < 0 || newCol >= this.MAP_COLS) {
                        return false;
                    }
                    
                    // 检查是否与已有方块重叠
                    if (this.map[newRow][newCol] === 1) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    
    /**
     * 向下移动方块
     * @returns 是否移动成功
     */
    moveDown(): boolean {
        if (this.checkPositionValid(this.currentRow + 1, this.currentCol)) {
            this.currentRow++;
            this.updateBlockPosition();
            return true;
        } else {
            // 方块无法继续下落，固定到地图上
            this.fixBlockToMap();
            return false;
        }
    }
    
    /**
     * 左右移动方块
     * @param direction 方向（-1左移，1右移）
     * @returns 是否移动成功
     */
    moveHorizontal(direction: number): boolean {
        if (this.checkPositionValid(this.currentRow, this.currentCol + direction)) {
            this.currentCol += direction;
            this.updateBlockPosition();
            return true;
        }
        return false;
    }
    
    /**
     * 旋转方块
     * @returns 是否旋转成功
     */
    rotate(): boolean {
        // 保存当前方块状态
        const tempBlock = this.currentBlock;
        const tempRows = this.currentBlock.length;
        const tempCols = this.currentBlock[0].length;
        
        // 创建旋转后的方块（90度顺时针）
        const rotatedBlock: Node[][] = [];
        for (let i = 0; i < tempCols; i++) {
            rotatedBlock[i] = [];
            for (let j = 0; j < tempRows; j++) {
                rotatedBlock[i][j] = tempBlock[tempRows - 1 - j][i];
            }
        }
        
        // 临时替换方块进行碰撞检测
        this.currentBlock = rotatedBlock;
        
        // 检查旋转后的位置是否有效
        const isValid = this.checkPositionValid(this.currentRow, this.currentCol);
        
        if (isValid) {
            // 旋转有效，更新显示
            this.updateBlockPosition();
        } else {
            // 旋转无效，恢复原样
            this.currentBlock = tempBlock;
        }
        
        return isValid;
    }
    
    /**
     * 将方块固定到地图上
     * 当方块无法继续下落时调用
     */
    fixBlockToMap() {
        // 将方块数据写入地图
        for (let i = 0; i < this.currentBlock.length; i++) {
            for (let j = 0; j < this.currentBlock[i].length; j++) {
                if (this.currentBlock[i][j]) {
                    this.map[this.currentRow + i][this.currentCol + j] = 1;
                    // 保留方块在场景中作为静态显示
                    // 这里可以优化为添加到单独的容器节点
                }
            }
        }
        
        // 检查并消除完整的行
        this.checkLines();
        
        // 生成新方块
        this.spawnNewBlock();
    }
    
    /**
     * 检查并消除完整的行
     */
    checkLines() {
        let linesCleared = 0;
        
        for (let i = this.MAP_ROWS - 1; i >= 0; i--) {
            let isLineComplete = true;
            
            // 检查该行是否所有格子都被填满
            for (let j = 0; j < this.MAP_COLS; j++) {
                if (this.map[i][j] === 0) {
                    isLineComplete = false;
                    break;
                }
            }
            
            if (isLineComplete) {
                // 消除该行
                this.clearLine(i);
                linesCleared++;
                i++; // 重新检查当前行（因为上面的行会下落）
            }
        }
        
        // 更新分数
        if (linesCleared > 0) {
            this.gameManager.addScore(linesCleared);
        }
    }
    
    /**
     * 消除指定行
     * @param lineIndex 要消除的行索引
     */
    clearLine(lineIndex: number) {
        // 从该行为空，上面的行下落
        for (let i = lineIndex; i > 0; i--) {
            for (let j = 0; j < this.MAP_COLS; j++) {
                this.map[i][j] = this.map[i - 1][j];
            }
        }
        
        // 顶部行置空
        for (let j = 0; j < this.MAP_COLS; j++) {
            this.map[0][j] = 0;
        }
        
        // 这里可以添加消除动画效果
    }
    
    /**
     * 更新方法
     * 处理方块自动下落
     * @param deltaTime 帧间隔时间
     */
    update(deltaTime: number) {
        // 如果游戏结束则不再处理
        if (this.gameManager && this.gameManager.isGameOver) {
            return;
        }
        
        // 更新计时器
        this.dropTimer += deltaTime;
        
        // 达到下落间隔时自动下落
        if (this.dropTimer >= this.dropInterval) {
            this.dropTimer = 0;
            this.moveDown();
        }
    }
}